package com.youaishujuhui.devops.web.controller.host;

import java.util.List;

import org.nutz.dao.Cnd;
import org.nutz.dao.FieldFilter;
import org.nutz.dao.util.Daos;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.druid.util.StringUtils;
import com.youaishujuhui.devops.web.domain.channel.Channel;
import com.youaishujuhui.devops.web.domain.host.Host;
import com.youaishujuhui.devops.web.po.Select2PO;
import com.youaishujuhui.devops.web.service.channel.ChannelService;
import com.youaishujuhui.devops.web.service.game.GameProcessService;
import com.youaishujuhui.devops.web.service.host.HostService;
import com.youaishujuhui.devops.web.util.Common;
import com.youaishujuhui.devops.web.util.NetworkTool;
import com.youaishujuhui.devops.web.util.syslog.SystemLog;
import com.youaishujuhui.devops.web.vo.Result;

@Controller
@RequestMapping("/host/host")
public class HostController {
	
	@Autowired
    private HostService hostService;
	
	@Autowired
	private ChannelService channelService;
	
	@Autowired
	private GameProcessService gameProcessService;
	
    @RequestMapping("/page")
    public ModelAndView page(){
        return new ModelAndView("host/host");
    }
    
    @RequestMapping("/online_page")
    public ModelAndView onlinePage(){
        return new ModelAndView("host/online_host");
    }
    
    @RequestMapping("/offline_page")
    public ModelAndView offlinePage(){
        return new ModelAndView("host/offline_host");
    }
    
    @RequestMapping("/add")
    @ResponseBody
    @SystemLog(module = "主机管理", oper = "添加主机")
    public Result<String> add(Host po){
    	
    	if (StringUtils.isEmpty(po.getCmccIp())) {
    		po.setCmccIp(null);
    	}
    	
    	if (StringUtils.isEmpty(po.getCtccIp())) {
    		po.setCtccIp(null);
    	}
    	
    	if (StringUtils.isEmpty(po.getCuccIp())) {
    		po.setCuccIp(null);
    	}
    	
    	if (StringUtils.isEmpty(po.getRemark())) {
    		po.setRemark(null);
    	}
    	
        Result<String> result = new Result<>();
        
        try {
        	hostService._insert(po);
        } catch (Exception e) {
        	result.setCode(Result.FAIL);
            result.setMsg(e.getMessage());
            return result;
        }
        
        result.setCode(Result.SUCCESS);
        result.setMsg("添加成功");

        return result;
    }
    
    @SystemLog(module = "主机管理", oper = "修改主机")
    @RequestMapping("/edit")
    @ResponseBody
    public Result<String> edit(Host po){
        Result<String> result = new Result<>();
        
        if (StringUtils.isEmpty(po.getCmccIp())) {
    		po.setCmccIp(null);
    	}
    	
    	if (StringUtils.isEmpty(po.getCtccIp())) {
    		po.setCtccIp(null);
    	}
    	
    	if (StringUtils.isEmpty(po.getCuccIp())) {
    		po.setCuccIp(null);
    	}
    	
    	if (StringUtils.isEmpty(po.getRemark())) {
    		po.setRemark(null);
    	}
    	
        Host oldHost = hostService.fetch(po.getHostId());
        
        int existChannelCnt = channelService.count(Cnd.where("property", "=", oldHost.getProperty()));
        
        if (existChannelCnt > 0 && !(oldHost.getProperty().equals(po.getProperty()))) {
        	result.setCode(Result.FAIL);
            result.setMsg("此主机的出机方已关联渠道，不允许修改出机方");
            return result;
        }
        
        if (oldHost.getCurGameServerCount() > po.getMaxGameServerCount()) {
        	result.setCode(Result.FAIL);
            result.setMsg("当前主机装服数量大于新设置的最大装服数，不允许修改");
            return result;
        }

        // 忽略以下字段更新，且不忽略空值
        FieldFilter fm = FieldFilter.create(Host.class, null, 
        		"^hostId|curGameServerCount|state|createTime$", false);
        
        Daos.ext(hostService.dao(), fm).update(po);

        result.setCode(Result.SUCCESS);
        result.setMsg("修改成功！");
        return result;
    }
    
    @SystemLog(module = "主机管理", oper = "回收主机")
    @RequestMapping("/del")
    @ResponseBody
    public Result<String> delete(Integer id){
        Result<String> result = new Result<>();
        
        if (gameProcessService.count(Cnd.where("hostId", "=", id).
        		and("state", "=", 1)) > 0) {
        	result.setCode(Result.FAIL);
            result.setMsg("还有游戏服部署在此主机，不允许回收");
            return result;
        }
        
        Host host = hostService.fetch(id);
        
        if (hostService.count(Cnd.where("property", "=", host.getProperty()).and("state", "=", Common.HOST_STATE_ONLINE)) == 1
        		&& channelService.count(Cnd.where("property", "=", host.getProperty())) > 0) {
        	result.setCode(Result.FAIL);
            result.setMsg("还有渠道的出机方关联此主机的出机方，不允许回收");
            return result;
        }
        
        host.setHostId(id);
        host.setState(Common.HOST_STATE_DELETE);
        hostService._update(host, "^state$");
        
        result.setCode(Result.SUCCESS);
        result.setMsg("回收成功！");
        return result;
    }
    
    @RequestMapping("/online")
    @ResponseBody
    public Result<String> online(Integer id){
        Result<String> result = new Result<>();
        
        Host host = hostService.fetch(id);
        
        if (host.getState() == Common.HOST_STATE_UNINIT) {
        	result.setCode(Result.FAIL);
            result.setMsg("该主机尚未初始化，不能上架！");
            return result;
        }

        host.setState(Common.HOST_STATE_ONLINE);
     
        hostService._update(host, "^state$");
        
        result.setCode(Result.SUCCESS);
        result.setMsg("上架主机成功！");
        return result;
    }
    
    @RequestMapping("/offline")
    @ResponseBody
    public Result<String> offline(Integer id){
        Result<String> result = new Result<>();
        
        if (gameProcessService.count(Cnd.where("hostId", "=", id).
        		and("state", "=", 1)) > 0) {
        	result.setCode(Result.FAIL);
            result.setMsg("还有游戏服部署在此主机，不允许下架");
            return result;
        }
        
        Host host = hostService.fetch(id);
        
        if (hostService.count(Cnd.where("property", "=", host.getProperty()).and("state", "=", Common.HOST_STATE_ONLINE)) == 1
        		&& channelService.count(Cnd.where("property", "=", host.getProperty())) > 0) {
        	result.setCode(Result.FAIL);
            result.setMsg("还有渠道的出机方关联此主机的出机方，不允许下架");
            return result;
        }
        
        host.setHostId(id);
        host.setState(Common.HOST_STATE_OFFLINE);
     
        hostService._update(host, "^state$");
        
        result.setCode(Result.SUCCESS);
        result.setMsg("下架主机成功！");
        return result;
    }
    
    @RequestMapping("/findById")
    @ResponseBody
    public Result<Host> findById(Integer id){
        Result<Host> result = new Result<>();
        Host po = hostService.fetch(id);
        if(po == null){
            result.setCode(Result.FAIL);
            result.setMsg(String.format("记录已不存在！"));
        } else {
        	po = hostService._fetchLinks(po, null);
            result.setCode(Result.SUCCESS);
            result.setData(po);
        }

        return result;
    }
    
    @RequestMapping("/ping")
    @ResponseBody
    public Result<Boolean> ping(String ip) {
    	Result<Boolean> result = new Result<>();
    	
    	boolean status = NetworkTool.ping(ip);
 
    	result.setData(status);
        result.setCode(Result.SUCCESS);
        result.setMsg(status ? "ping成功" : "ping失败");
    	return result;
    }
    
    @RequestMapping("/query")
    @ResponseBody
    public Result<List<Host>> query(){
        
        Result<List<Host>> result = new Result<>();

        List<Host> list = hostService.dao().queryByJoin(Host.class, "game", Cnd.where("t_host.state", ">=", 0));

        result.setData(list);
        result.setCode(Result.SUCCESS);

        return result;
    }
    
    @RequestMapping("/queryOnline")
    @ResponseBody
    public Result<List<Host>> queryOnline(){
        
        Result<List<Host>> result = new Result<>();

        List<Host> list = hostService.dao().queryByJoin(Host.class, "game", Cnd.where("t_host.state", "=", Common.HOST_STATE_ONLINE));

        result.setData(list);
        result.setCode(Result.SUCCESS);

        return result;
    }
    
    @RequestMapping("/queryOffline")
    @ResponseBody
    public Result<List<Host>> queryOffline(){
        
        Result<List<Host>> result = new Result<>();

        List<Host> list = hostService.dao().queryByJoin(Host.class, "game", Cnd.where("t_host.state", "<>", Common.HOST_STATE_ONLINE).and("t_host.state", "<>", Common.HOST_STATE_DELETE));

        result.setData(list);
        result.setCode(Result.SUCCESS);

        return result;
    }
    
    @RequestMapping("/queryProperty")
    @ResponseBody
    public Result<List<Select2PO>> queryProperty(String gameId) {
    	Result<List<Select2PO>> result = new Result<>();
    	
    	List<Select2PO> list = hostService.queryProperty(gameId);
    	
    	result.setData(list);
        result.setCode(Result.SUCCESS);
    	
    	return result;
    }
    
    @RequestMapping("/queryBestDeployHost")
    @ResponseBody
    public Result<List<Select2PO>> queryBestDeployHost(int gameId, int channelId) {
    	Result<List<Select2PO>> result = new Result<>();
    	
    	Channel channel = channelService.fetch(channelId);
    	
    	List<Select2PO> list = hostService.queryBestDeployHost(gameId, channel.getProperty());
    	
    	result.setData(list);
        result.setCode(Result.SUCCESS);
    	
    	return result;
    }
    
    
}
